/**********************************************************************************************/
// dgt_Circuit.cpp
//
// Common Lib for Digital Studio
// Class, which represent generated circuit
//
// Copyright Diamant Group 2008
/**********************************************************************************************/

#include "DStudio.h"
#include "dgt_Circuit.h"
#include "dgt_Utils.h"

/**********************************************************************************************/
dgt_Circuit::dgt_Circuit( dgt_CrcContactArray	inInputs,
						dgt_CrcContactArray		inOutputs,
						dgt_CrcElementArray		inElements,
						dgt_CrcLinkArray		inLinks )
{
	for( unsigned i = 0; i < inInputs.Count(); i++ )
	{
		dgt_CircuitContact_Ptr tItem = inInputs.Item( i );

		m_Inputs.Add( tItem );		
	}

	for( unsigned i = 0; i < inOutputs.Count(); i++ )
	{
		dgt_CircuitContact_Ptr tItem = inOutputs.Item( i );

		m_Outputs.Add( tItem );		
	}

	for( unsigned i = 0; i < inElements.Count(); i++ )
	{
		dgt_CircuitElement_Ptr tItem = inElements.Item( i );

		m_Elements.Add( tItem );
	}

	for( unsigned i = 0; i < inLinks.Count(); i++ )
	{
		dgt_CircuitLink_Ptr tItem = inLinks.Item( i );

		m_Links.Add( tItem );		
	}
}

/**********************************************************************************************/
dgt_Circuit::dgt_Circuit(dgt_BoolFunction_Ptr inFunction )
{
	BoolElementArray tArray = inFunction->get_Function();
	wxArrayString tNames = inFunction->get_VarNames();

	for( unsigned i = 0; i < tArray.Count(); i++ )
	{
		dgt_BoolElement_Ptr tElement = tArray.Item( i );
		
		pair< wxString, unsigned > tData = get_LibAndNum( tElement );
		dgt_CircuitElement_Ptr tCrc( new dgt_CircuitElement( tData.first, tData.second ) );

		this->add_Element( tCrc );
	}

	for( unsigned i = 0; i < tArray.Count(); i++ )
	{
		dgt_BoolElement_Ptr tElement = tArray.Item( i );

		wxArrayInt tOperands = tElement->get_OpCodes();
		wxBoolArray tInverts = tElement->get_Inverts();

		for( unsigned j = 0; j < tElement->Count(); j++ )
		{
			int t_Op = tOperands.Item( j );
			if( t_Op > 0 )
			{
				wxString name = tNames.Item( t_Op );
				if( !(tInverts.Item( j )) )
					name.Prepend( _("!") );

				dgt_CircuitContact_Ptr tCont( new dgt_CircuitContact( name, i, j, 0 ) );
				this->add_Input( tCont );
			}
			else if ( t_Op < 0 )
			{
				unsigned elNum = -( t_Op + 1 );
				
				dgt_CircuitLink_Ptr TLink( new dgt_CircuitLink( elNum, 0, i, j ));
				this->add_Link( TLink );
			}
		}
	}
}

/**********************************************************************************************/							
dgt_CircuitElement_Ptr dgt_Circuit::get_Element( unsigned inNum )
{
	return m_Elements.Item( inNum );
}

/**********************************************************************************************/
dgt_CrcElementArray dgt_Circuit::get_Elements( void )
{
	return m_Elements;
}

/**********************************************************************************************/
void dgt_Circuit::add_Element( dgt_CircuitElement_Ptr inElement )
{
	m_Elements.Add( inElement );
}

/**********************************************************************************************/
void dgt_Circuit::set_Elements( dgt_CrcElementArray inElements )
{
	for( unsigned i = 0; i < inElements.Count(); i++ )
	{
		dgt_CircuitElement_Ptr tItem = inElements.Item( i );

		m_Elements.Add( tItem );
	}
}	

/**********************************************************************************************/
dgt_CircuitLink_Ptr dgt_Circuit::get_Link( unsigned inNum )
{
	return m_Links.Item( inNum );
}


/**********************************************************************************************/
dgt_CrcLinkArray dgt_Circuit::get_Links( void )
{
	return m_Links;
}

/**********************************************************************************************/
void dgt_Circuit::add_Link( dgt_CircuitLink_Ptr inLink )
{
	m_Links.Add( inLink );
}

/**********************************************************************************************/
void dgt_Circuit::set_Links( dgt_CrcLinkArray inLinks )
{
	m_Links.Clear();
	for( unsigned i = 0; i < inLinks.Count(); i++ )
	{
		dgt_CircuitLink_Ptr tItem = inLinks.Item( i );

		m_Links.Add( tItem );		
	}
}

/**********************************************************************************************/
unsigned dgt_Circuit::get_InputCount( void )
{
	return m_Links.Count();
}

/**********************************************************************************************/
dgt_CrcContactArray dgt_Circuit::get_Inputs( void )
{
	return m_Inputs;
}

/**********************************************************************************************/
void dgt_Circuit::add_Input( dgt_CircuitContact_Ptr inInput)
{
	m_Inputs.Add( inInput );
}

/**********************************************************************************************/
dgt_CircuitContact_Ptr dgt_Circuit::get_Input( unsigned inNum )
{
	return m_Inputs.Item( inNum );
}
	
/**********************************************************************************************/
void dgt_Circuit::set_Inputs( dgt_CrcContactArray inInputs )
{
	m_Inputs.Clear();

	for( unsigned i = 0; i < inInputs.Count(); i++ )
	{
		dgt_CircuitContact_Ptr tItem = inInputs.Item( i );

		m_Inputs.Add( tItem );		
	}
}

/**********************************************************************************************/
unsigned dgt_Circuit::get_OutputCount( void )
{
	return m_Outputs.Count();
}

/**********************************************************************************************/
dgt_CrcContactArray	dgt_Circuit::get_Outputs( void )
{
	return m_Outputs;
}

/**********************************************************************************************/
void dgt_Circuit::add_Output( dgt_CircuitContact_Ptr inOutput)
{
	m_Outputs.Add( inOutput );
}

/**********************************************************************************************/
dgt_CircuitContact_Ptr dgt_Circuit::get_Output( unsigned inNum )
{
	return m_Outputs.Item( inNum );
}

/**********************************************************************************************/
void dgt_Circuit::set_Outputs( dgt_CrcContactArray inOutputs )
{
	m_Outputs.Clear();

	for( unsigned i = 0; i < inOutputs.Count(); i++ )
	{
		dgt_CircuitContact_Ptr tItem = inOutputs.Item( i );

		inOutputs.Add( tItem );		
	}
}


